class UserSettings
  attr_accessor :default_state, :default_special, :default_resp, :toggle
  
  def initialize
    @default_state   = '0'
    @default_special = '0'
    @default_resp    = '0'
    @toggle = 'hide'
  end
  
end

# this model expects a certain database layout and its based on the name/login pattern. 
class User < ActiveRecord::Base
  include ApplicationHelper
  
  has_many :tasks
  has_many :notes
  has_many :membership
  has_many :bookmarks
  has_many :projects, :through=>:membership, :select => "memberships.active, projects.*"

  serialize :settings, UserSettings

  def self.authenticate(login, pass)
    find(:first, :conditions=>["login=? AND password=?", login,  ApplicationHelper.sha1(pass)])
  end  
  
  def self.find_with_cookie(value)
    User.find(:all).each { |u|
      return u if value ==  ApplicationHelper.sha1(u.login+u.password)
      }
    return nil  
  end
  
  def accept_invitation(inv_arr) # TODO: test multiple invitations
    inv_arr.each { |i|
      p = Project.find(i.project_id)
      projects << p if not projects.member?(p)
      i.destroy
    }
  end
  
  def decline_invitation(inv_arr) # TODO: test multiple invitations
    inv_arr.each { |i|
      i.destroy
    }
  end

  def inbox_tasks
    ids = active_projects_ids
    return [] if ids == []
    Task.find(:all,:conditions=>"user_id=#{self.id} and done=0 and state='inbox' and (project_id=0 or project_id in (#{ids.join(',')}))").sort_by{|t| t.project_id}
  end

  def without_project
    Task.find(:all,:conditions=>"project_id=0 and user_id=#{self.id} and done=0 and state!='inbox'")
  end

 
  def late_tasks
    # TODO replace by Task.find (?)
    tasks.select{|t| t.done==0 and t.duedate and t.duedate <= Date.today and t.duedate >= Date.today-8}
  end
  
  def active_projects
    projects.select{|p| p.active=='1'}.sort_by {|p| [p.name.upcase]}
  end
  
  def active_projects_ids
    projects.select{|p| p.active=='1'}.collect{|p| p.id}
  end
      
  def toggle
    settings.toggle = (settings.toggle=='display'? 'hide':'display')
    save
  end
  
  def check_task_rights(task_id)
    t = Task.find(task_id)
    return true if t.user_id=id or projects.collect{|p| p.id}.include?(t.project_id)
    return false
  end
  
  def coworkers
    users = []
    self.active_projects.each { |p|
      p.users.each { |u| users << u}
      }
    users.uniq!
	users
  end
  
  protected

  before_create :crypt_password
  before_update :crypt_password_on_update
  
  def crypt_password
    write_attribute("password",  ApplicationHelper.sha1(password))
  end
  
  validates_length_of :name, :within => 1..40
  validates_length_of :login, :within => 1..40
  validates_length_of :password, :within => 4..40
  validates_presence_of :login, :name
  validates_uniqueness_of :login, :case_sensitive => false
  validates_uniqueness_of :name, :case_sensitive => false # also the name as we assign users to projects by name
  validates_uniqueness_of :email, :case_sensitive => false, :if => Proc.new {|u| u.email and not u.email.empty?}
  validates_presence_of :password, :password_confirmation, :if => :validate_password_confirmation?
  validates_confirmation_of :password,:if => :validate_password_confirmation?
  
  def crypt_password_on_update
    crypt_password if validate_password_confirmation?
  end
  
  def validate_password_confirmation?
    (password and password_confirmation)
  end  
  
end

